package se.webbzon.boltzmann.game.object.dialogue.word;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;

import se.webbzon.boltzmann.game.object.dialogue.AbstractDialogue;
import se.webbzon.boltzmann.game.object.dialogue.layout.DialogueLayout;
import se.webbzon.boltzmann.resource.Resources;
import se.webbzon.oschi01.worldobject.appearance.Appearance3D;
import se.webbzon.oschi01.worldobject.appearance.TextAppearance3D;

public abstract class SimpleDialogueWord extends AbstractDialogueWord {
	
	// The default color of the word
	private static final Color defaultColor = Color.black;
	
	// The default font used to print dialogue words
	private static final Font defaultFont = Resources.getFont("liberation_mono_plain").deriveFont(30f);
	
	// The word to print (may be null)
	private String word;
		
	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new simple dialogue word with a layout but without
	 * a text. The method getWord() must be override by the subclass
	 * if this constructor is used. **/
	public SimpleDialogueWord(DialogueLayout layout) {
		this(layout,null,defaultColor);
	}
	
	/** Creates a new simple dialogue word with a layout and a text.
	 * The word may be null but only if the method getWord() is 
	 * override by the subclass. **/
	public SimpleDialogueWord(	DialogueLayout layout, 
								String word) {
		this(layout,word,defaultColor);
	}
	
	/** Creates a new simple dialogue word with a layout and a text. 
	 * A word color must be provided upon creation. The word may be null
	 * but only if the method getWord() is override by the subclass. **/
	public SimpleDialogueWord(DialogueLayout layout, String word, Color color) {
		super(layout, createAppearance(color));
		this.word = word;
	}
		
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the default font of the abstract dialogue word. **/
	public static Font getDefaultFont() {
		return defaultFont;
	}
	
	/** Returns the default color of the abstract dialogue word. **/
	public static Color getDefaultColor() {
		return defaultColor;
	}

	@Override public void getDimension(Dimension d) {
		final DialogueLayout layout = getLayout();
		d.setSize(	getWord().length() * layout.getCharacterWidth(),
					layout.getCharacterHeight());
	}

	@Override public String getWord() {
		return word;
	}
	
	/** Sets the content of this dialogue word from the given string. 
	 * If this word is a part of an sentence then this method should 
	 * only be called from within the method onUpdateWord(). **/
	public void setWord(String word) {
		this.word = word;
	}
	
	@Override public void onUpdateWord(AbstractDialogue dialogue) {};
	
	@Override public void onShowCharacter(AbstractDialogue dialogue, int character) {
		DialogueLayout layout = getLayout();
		TextAppearance3D appearance = (TextAppearance3D) getAppearance();
		appearance.setText(getWord().substring(0, character));
		
		setSize(layout.getCharacterWidth() * character,
				layout.getCharacterHeight(),
				1);
	}
	
	@Override public final void onShowAllCharacters(AbstractDialogue dialogue) {
		onShowCharacter(dialogue,getWord().length());
	}

	@Override public boolean isNewLine() {
		return false;
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Creates the appearance of this simple dialogue word. **/
	private static final Appearance3D createAppearance(Color color) {
		TextAppearance3D appearance = 
				new TextAppearance3D(	1,
										TextAppearance3D.ALIGN_LEFT+
										TextAppearance3D.ALIGN_TOP+
										TextAppearance3D.LAYERS+
										TextAppearance3D.KEEP_PROPORTIONS,
										defaultFont,
										"");
		appearance.setColor(color);
		appearance.setLayer(0,0,1);
		return appearance;
	}

}
